﻿using HK.Core.Serializable.Attribute;
using HK.Editor.GUIEx.Styles;
using HK.Editor.Serializable.Protocol.Drawer;
using HK.Editor.Utils;
using UnityEditor;
using UnityEngine;

namespace HK.Editor.Serializable.Drawer
{
    /// <summary>
    /// Drawer - 可序列化资产版本
    /// </summary>
    [CustomPropertyDrawer(typeof(SVersionAttribute))]
    public class SVersionDrawer : GUIPropertyDrawer<SVersionAttribute>, ISVersionDrawer
    {

#region SerializedProperty

        /// <summary>
        /// 取得版本显示信息
        /// <para>* 格式 : Max.Mid.Min.Tag</para>
        /// </summary>
        /// <param name="iVersionProperty"></param>
        /// <returns>版本显示信息</returns>
        private static string GetVersionDisplayInfo(SerializedProperty iVersionProperty)
        {
            if (null == iVersionProperty) return null;

            var maxProperty = iVersionProperty.FindPropertyRelative("max");
            var midProperty = iVersionProperty.FindPropertyRelative("mid");
            var minProperty = iVersionProperty.FindPropertyRelative("min");
            var tagProperty = iVersionProperty.FindPropertyRelative("tag");

            return string.IsNullOrEmpty(tagProperty.stringValue)
                ? $"{maxProperty.intValue}.{midProperty.intValue}.{minProperty.intValue}"
                : $"{maxProperty.intValue}.{midProperty.intValue}.{minProperty.intValue}.{tagProperty.stringValue}";
        }
        
        /// <summary>
        /// 初始化序列化Property信息
        /// </summary>
        /// <param name="iSelf">自身Property</param>
        /// <returns>true:OK; false:NG;</returns>
        protected override bool InitSerializedProperties(SerializedProperty iSelf)
        {
            if (!base.InitSerializedProperties(iSelf)) return false;
            
            // 只读
            if (ReadOnly)
            {
                SelfProperty.isExpanded = false;
            }
            
            return true;
        }

#endregion

#region Content

        private GUIContent _versionInfo = null;

        /// <summary>
        /// 初始化Content
        /// </summary>
        /// <param name="iAttr">Attribute</param>
        /// <param name="iProperty">Property</param>
        /// <param name="iLabel">默认标题</param>
        protected override void InitContents(SVersionAttribute iAttr, SerializedProperty iProperty, GUIContent iLabel)
        {
            base.InitContents(iAttr, iProperty, iLabel);

            _versionInfo = UtilsGUIEx.CreateGuiContent(GetVersionDisplayInfo(SelfProperty));
        }

#endregion

#region Size&Rect

        private const float VersionInfoWidth = 80.0f;
        
#endregion

#region Draw

        /// <summary>
        /// 绘制GUI
        /// </summary>
        /// <param name="iRect">绘制矩形区域</param>
        /// <param name="iProperty">Property</param>
        /// <param name="iLabel">标题</param>
        public override void OnGUI(Rect iRect, SerializedProperty iProperty, GUIContent iLabel)
        {

            // 初始化
            InitSerializedProperties(iProperty);
            InitContents(SelfAttr, SelfProperty, iLabel);
                    
            // 当前Event
            var curEvent = Event.current;
            
            // 绘制标题
            var captionRect = iRect;
            captionRect.yMin += 2;
            captionRect.height = SingleLineHeight + VerticalSpacing;
            captionRect = DrawCaption(captionRect, curEvent, Caption);
            
            // 只读的话只绘制标题
            if(ReadOnly || !IsExpanded) return;
            
            // 绘制自身
            var selfRect = iRect;
            selfRect.yMin = captionRect.yMax + VerticalSpacing;
            DrawSelf(selfRect, curEvent);
        }

#region Caption

        /// <summary>
        /// 绘制标题
        /// </summary>
        /// <param name="iRect">绘制矩形区域</param>
        /// <param name="iEvent">Event</param>
        /// <param name="iCaption">标题</param>
        /// <returns>绘制的矩形区域</returns>
        protected override Rect DrawCaption(Rect iRect, Event iEvent, GUIContent iCaption)
        {
            var displayRect = iRect;
            // 只读
            if (ReadOnly)
            {
                var labelRect = displayRect;
                labelRect.xMin += LabelIntent;
                labelRect = UtilsGUIEx.DrawLabel(labelRect, iEvent, Caption, _versionInfo);
                
                return displayRect;
            }
            
            displayRect = base.DrawCaption(iRect, iEvent, iCaption);
            var versionWidth = displayRect.width * 0.4f;
            versionWidth = Mathf.Max(versionWidth, VersionInfoWidth);
            var versionRect = displayRect;
            //versionRect.xMax -= LabelIntent;
            versionRect.xMin = versionRect.xMax - versionWidth;

            // 时时更新版本信息
            if (null != _versionInfo)
            {
                _versionInfo.text = GetVersionDisplayInfo(SelfProperty);
            }
            
            versionRect = UtilsGUIEx.DrawLabel(versionRect, iEvent, _versionInfo, GuiExHelper.MiddleRightLabel);
            
            return displayRect;
        }

#endregion

#region Draw

        /// <summary>
        /// 绘制GUI
        /// </summary>
        /// <param name="iRect">绘制矩形区域</param>
        /// <param name="iEvent">Event</param>
        /// <returns>绘制范围</returns>
        protected override Rect DrawSelf(Rect iRect, Event iEvent)
        {
            var displayRect = iRect;
            if (!IsExpanded) return displayRect;
                            
            var dragMarkRect = displayRect;
            dragMarkRect.y = displayRect.yMin + VerticalSpacing;
            dragMarkRect.width = DragMarkWidth;
            dragMarkRect.height = SingleLineHeight;
            dragMarkRect = UtilsGUIEx.DrawDragMark(dragMarkRect, iEvent);
                            
            var bodyBgRect = displayRect;
            bodyBgRect.xMin = dragMarkRect.xMax + HorizontalSpacing;
            bodyBgRect.xMax -= HorizontalSpacing;
            bodyBgRect.yMin = displayRect.yMin - 1;
            bodyBgRect.yMax = displayRect.yMax - VerticalSpacing;
            bodyBgRect = UtilsGUIEx.DrawGenericBg(bodyBgRect, iEvent);
                                
            bodyBgRect.xMin += HorizontalSpacing;
            bodyBgRect.xMax -= HorizontalSpacing;
            bodyBgRect.yMin += VerticalSpacing;
            bodyBgRect.yMax -= VerticalSpacing;
            bodyBgRect = DrawElements(bodyBgRect, iEvent, SelfProperty);

            return displayRect;
        }

#endregion
        
#endregion
        
    }
}
